package rabbitas {
	import mx.controls.Alert;

	/**
	 * @author martindyrby
	 */
	public class Reflector {
		static private var varexp:RegExp = /\{[^\}]+\}/gi;
		
		static public function reflectStringValue(input:String, instanceManager:InstanceManager = null) : * {
			RabbitLogger.debug("reflectStringValue", input);
			var cleanInput:* = resolveExpressions(input,instanceManager);
			RabbitLogger.debug("resolveExpressions", cleanInput);
			
			if(cleanInput is String) {
				if(isArray(cleanInput)) {
					var valueArray : Array = getArrayFromString(cleanInput);
					valueArray.forEach(function(item : String, index : int, array : Array) : void {
						array[index] = reflectStringValue(item, instanceManager);
					});
					return valueArray;
				} else if(isObject(cleanInput)) {
					var tmpArray : Array = getArrayFromString(cleanInput);
					var valueObject : Object = new Object();
					tmpArray.forEach(function(item : String, index : int, array : Array) : void {
						valueObject[item.substr(0, item.indexOf(':'))] = reflectStringValue(item.substr(item.indexOf(':')+1), instanceManager);
					});
					return valueObject;
				} else if(isNumber(cleanInput)) {
					return Number(cleanInput);
				}
			}
			
			return cleanInput;
		}

		private static function resolveExpressions(input : String, instanceManager:InstanceManager) : * {
			var varmatches : Array = input.match(varexp);
			RabbitLogger.debug("matches",varmatches.toString());
			var replacements:Object = new Object();
			varmatches.forEach(function(item : String, index : int, array : Array) : void {
				replacements[item] = instanceManager.getObjectById(getVarNameFromString(item));
			});

			for (var s:String in replacements) {
				if (s == input) return replacements[s];
				input = input.replace(s, replacements[s]);
			}
			RabbitLogger.debug("resolveExpressions return",input);
			return input;
		}

		private static function isObject(input : String) : Boolean {
			return input.indexOf("{") == 0 && input.lastIndexOf("}") == input.length - 1 && input.indexOf(":") > -1;
		}

		private static function isNumber(input : String) : Boolean {
			return !isNaN(Number(input));
		}

		private static function getVarNameFromString(input : String) : String {
			return input.substr(1, input.length - 2);;
		}

		private static function getArrayFromString(input : String) : Array {
			return getVarNameFromString(input).split(',');
		}

		private static function isArray(input : String) : Boolean {
			return input.indexOf("[") == 0 && input.lastIndexOf("]") == input.length - 1;
		}

		private static function isVariable(input : String) : Boolean {
			return input.indexOf("{") == 0 && input.lastIndexOf("}") == input.length - 1 && input.indexOf(":") == -1;
		}
	}
}
